package com.starry.module.system.core.oauth2.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.starry.core.common.constants.CommonError;
import com.starry.core.common.domain.vo.PageVo;
import com.starry.core.common.execption.ServiceException;
import com.starry.db.core.enums.DBEnableDisableStatusEnum;
import com.starry.db.core.query.LambdaQueryWrapperX;
import com.starry.module.system.api.oauth2.domain.qo.Oauth2ThirdClientPageQo;
import com.starry.module.system.api.oauth2.domain.qo.Oauth2ThirdClientQo;
import com.starry.module.system.api.oauth2.domain.vo.Oauth2ThirdClientDtlVo;
import com.starry.module.system.api.oauth2.domain.vo.Oauth2ThirdClientListVo;
import com.starry.module.system.api.oauth2.domain.vo.Oauth2ThirdClientVo;
import com.starry.module.system.core.oauth2.authorization.third.ThireClientFactory;
import com.starry.module.system.core.oauth2.entity.Oauth2ThirdClient;
import com.starry.module.system.core.oauth2.mapper.Oauth2ThirdClientMapper;
import com.starry.module.system.core.oauth2.service.Oauth2ThirdClientService;
import lombok.SneakyThrows;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 第三方客户端-服务实现
 *
 * @author xiaoke
 */
@Service("oauth2ThirdClientService")
public class Oauth2ThirdClientServiceImpl implements Oauth2ThirdClientService {

    private final Oauth2ThirdClientMapper oauth2ThirdClientMapper;
    private final ThireClientFactory thireClientFactory;

    @Lazy
    public Oauth2ThirdClientServiceImpl(Oauth2ThirdClientMapper oauth2ThirdClientMapper, ThireClientFactory thireClientFactory) {
        this.oauth2ThirdClientMapper = oauth2ThirdClientMapper;
        this.thireClientFactory = thireClientFactory;
    }

    @Override
    public PageVo<Oauth2ThirdClientVo> page(Oauth2ThirdClientPageQo pageQo) {
        PageVo<Oauth2ThirdClient> page = oauth2ThirdClientMapper.selectPage(pageQo);
        List<Oauth2ThirdClientVo> vos = BeanUtil.copyToList(page.getRows(), Oauth2ThirdClientVo.class);
        return new PageVo<>(vos, page.getTotal());
    }

    @Override
    public Oauth2ThirdClientDtlVo getById(Long id) {
        Oauth2ThirdClient oauth2ThirdClient = oauth2ThirdClientMapper.selectById(id);
        if (oauth2ThirdClient == null) {
            throw new ServiceException(CommonError.DATA_NOT_EXISTS.getMsg());
        }
        return BeanUtil.toBean(oauth2ThirdClient, Oauth2ThirdClientDtlVo.class);
    }

    @Override
    public Oauth2ThirdClient getByClientCode(String code) {
        return oauth2ThirdClientMapper.selectByClientCode(code);
    }

    @Transactional
    @Override
    public Long save(Oauth2ThirdClientQo oauth2ThirdClientQo) {
        LambdaQueryWrapperX<Oauth2ThirdClient> wrapper = new LambdaQueryWrapperX<>();
        wrapper
                .eq(Oauth2ThirdClient::getCode, oauth2ThirdClientQo.getCode());
        if (oauth2ThirdClientMapper.selectCount(wrapper) > 0) {
            throw new ServiceException(CommonError.DATA_EXISTS.getMsg());
        }
        Oauth2ThirdClient oauth2ThirdClient = BeanUtil.toBean(oauth2ThirdClientQo, Oauth2ThirdClient.class);
        oauth2ThirdClient.setId(null);
        oauth2ThirdClientMapper.insert(oauth2ThirdClient);

        return oauth2ThirdClient.getId();
    }

    @SneakyThrows
    @Transactional
    @Override
    public void updateById(Oauth2ThirdClientQo oauth2ThirdClientQo) {
        if (oauth2ThirdClientQo.getId() == null) {
            throw new ServiceException(CommonError.DATA_NOT_EXISTS.getMsg());
        }
        LambdaQueryWrapperX<Oauth2ThirdClient> wrapper = new LambdaQueryWrapperX<>();
        wrapper
                .ne(Oauth2ThirdClient::getId, oauth2ThirdClientQo.getId())
                .and(w ->
                        w.eq(Oauth2ThirdClient::getCode, oauth2ThirdClientQo.getCode())
                );
        if (oauth2ThirdClientMapper.selectCount(wrapper) > 0) {
            throw new ServiceException(CommonError.DATA_EXISTS.getMsg());
        }
        Oauth2ThirdClient oauth2ThirdClient = oauth2ThirdClientMapper.selectById(oauth2ThirdClientQo.getId());
        if (oauth2ThirdClient == null) {
            throw new ServiceException(CommonError.DATA_NOT_EXISTS.getMsg());
        }
        BeanUtil.copyProperties(oauth2ThirdClientQo, oauth2ThirdClient);
        oauth2ThirdClientMapper.updateById(oauth2ThirdClient);

        thireClientFactory.reloadClient(oauth2ThirdClient);
    }

    @Transactional
    @Override
    public void removeByIds(Set<Long> idList) {
        if (idList.isEmpty()) return;
        oauth2ThirdClientMapper.deleteByIds(idList);
    }

    @Transactional
    @Override
    public void enable(Set<Long> idList) {
        if (idList.isEmpty()) return;
        oauth2ThirdClientMapper.updateBatch(setOauth2ThirdClientStatus(idList, DBEnableDisableStatusEnum.ENABLE));
    }

    @Transactional
    @Override
    public void disable(Set<Long> idList) {
        if (idList.isEmpty()) return;
        oauth2ThirdClientMapper.updateBatch(setOauth2ThirdClientStatus(idList, DBEnableDisableStatusEnum.DISABLE));
    }

    @Override
    public List<Oauth2ThirdClientListVo> getClientList() {
        return BeanUtil.copyToList(oauth2ThirdClientMapper.selectClientList(), Oauth2ThirdClientListVo.class);
    }

    private Set<Oauth2ThirdClient> setOauth2ThirdClientStatus(Set<Long> idList, DBEnableDisableStatusEnum status) {
        Set<Oauth2ThirdClient> oauth2ThirdClients = new HashSet<>();
        idList.forEach(item -> {
            Oauth2ThirdClient oauth2ThirdClient = new Oauth2ThirdClient();
            oauth2ThirdClient.setId(item);
            oauth2ThirdClient.setStatus(status.getCode());
            oauth2ThirdClients.add(oauth2ThirdClient);
        });
        return oauth2ThirdClients;
    }


}

